//
//  NSDate+Utility.m
//  MyLawyerFoundation
//
//  Created by Jinxiao on 6/30/15.
//
//

#import "NSDate+Utility.h"

static const unsigned componentFlags = (NSCalendarUnitYear| NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekOfMonth |  NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitWeekday | NSCalendarUnitWeekdayOrdinal);


@implementation NSDate (Utility)

- (BOOL)earlierThan:(NSDate *)date
{
    return [self compare:date] == NSOrderedAscending;
}

- (BOOL)laterThan:(NSDate *)date
{
    return [self compare:date] == NSOrderedDescending;
}

- (BOOL)sameDayAs:(NSDate *)date
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *comp1 = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:self];
    NSDateComponents *comp2 = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:date];
    return comp1.day == comp2.day && comp1.month == comp2.month && comp1.year == comp2.year;
}

- (BOOL)sameYearAs:(NSDate *)date
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *comp1 = [calendar components:NSCalendarUnitYear fromDate:self];
    NSDateComponents *comp2 = [calendar components:NSCalendarUnitYear fromDate:date];
    return comp1.year == comp2.year;
}

- (BOOL)sameWeekAs:(NSDate *)date
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *comp1 = [calendar components:NSCalendarUnitYear|NSCalendarUnitWeekOfYear fromDate:self];
    NSDateComponents *comp2 = [calendar components:NSCalendarUnitYear|NSCalendarUnitWeekOfYear fromDate:date];
    return comp1.weekOfYear == comp2.weekOfYear && comp1.year == comp2.year;
}

- (BOOL)sameMonthAs:(NSDate *)date
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *comp1 = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth fromDate:self];
    NSDateComponents *comp2 = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth fromDate:date];
    return comp1.month == comp2.month && comp1.year == comp2.year;
}

- (NSDate *)previousDay
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *components = [[NSDateComponents alloc] init];
    components.day = -1;
    return [calendar dateByAddingComponents:components toDate:self options:0];
}

- (NSDate *)nextDay
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *components = [[NSDateComponents alloc] init];
    components.day = 1;
    return [calendar dateByAddingComponents:components toDate:self options:0];
}

- (NSDate *)nextWeek
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *components = [[NSDateComponents alloc] init];
    components.weekOfYear = 1;
    return [calendar dateByAddingComponents:components toDate:self options:0];
}

- (NSDate *)previousMonth
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *components = [[NSDateComponents alloc] init];
    components.month = -1;
    return [calendar dateByAddingComponents:components toDate:self options:0];
}

- (NSDate *)nextMonth
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *components = [[NSDateComponents alloc] init];
    components.month = 1;
    return [calendar dateByAddingComponents:components toDate:self options:0];
}

- (NSInteger)day
{
    NSDateComponents *components = [[[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian] components:(NSCalendarUnitMonth | NSCalendarUnitDay) fromDate: self];
    return components.day;
}

- (NSInteger)month
{
    NSDateComponents *components = [[[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian] components:(NSCalendarUnitMonth | NSCalendarUnitDay) fromDate: self];
    return components.month;
}

- (NSInteger)year
{
    NSDateComponents *components = [[[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian] components:NSCalendarUnitYear fromDate: self];
    return components.year;
}

- (NSInteger)weekDay
{
    NSDateComponents *components = [[[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian] components:NSCalendarUnitWeekday fromDate: self];
    
    return components.weekday;
}

- (NSDate *)dateAtStartOfMonth
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    
    NSDate *date = nil;
    [calendar rangeOfUnit:NSCalendarUnitMonth startDate:&date interval:0 forDate:self];
    
    NSDateComponents *components = [calendar components:componentFlags fromDate:date];
    components.hour = 0;
    components.minute = 0;
    components.second = 0;
    return [calendar dateFromComponents:components];
}

- (NSDate *)dateAtEndOfMonth
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    
    NSRange range = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:self];
    NSDateComponents *components = [calendar components:componentFlags fromDate:self];
    components.day = range.length;
    components.hour = 23;
    components.minute = 59;
    components.second = 59;
    return [calendar dateFromComponents:components];
}

- (NSDate *)dateAtStartOfWeek
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    [calendar setFirstWeekday:2];
    NSDate *date = nil;
    [calendar rangeOfUnit:NSCalendarUnitWeekOfMonth startDate:&date interval:nil forDate:self];
    
    NSDateComponents *components = [calendar components:componentFlags fromDate:date];
    components.hour = 0;
    components.minute = 0;
    components.second = 0;
    return [calendar dateFromComponents:components];
}

- (NSDate *)dateAtEndOfWeek
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    [calendar setFirstWeekday:2];
    NSDateComponents *components = [calendar components:componentFlags fromDate:self];
    components.day += [calendar maximumRangeOfUnit:NSCalendarUnitWeekday].length - components.weekday + 1;
    components.hour = 23;
    components.minute = 59;
    components.second = 59;
    return [calendar dateFromComponents:components];
}


- (NSDate *)dateAtStartOfDay
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *components = [calendar components:componentFlags fromDate:self];
    components.hour = 0;
    components.minute = 0;
    components.second = 0;
    return [calendar dateFromComponents:components];
}

- (NSDate *)dateAtEndOfDay
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *components = [calendar components:componentFlags fromDate:self];
    components.hour = 23;
    components.minute = 59;
    components.second = 59;
    return [calendar dateFromComponents:components];
}

- (NSDate *)dateAtStartOfYear
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    
    NSDateComponents *components = [calendar components:componentFlags fromDate:self];
    NSRange monthRange = [calendar rangeOfUnit:NSCalendarUnitMonth inUnit:NSCalendarUnitYear forDate:self];
    NSRange dayRange = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:self];
    components.day = dayRange.location;
    components.month = monthRange.location;
    NSDate *startOfYear = [calendar dateFromComponents:components];
    return startOfYear;
}

- (NSDate *)dateAtEndOfYear
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *components = [calendar components:componentFlags fromDate:self];
    NSRange monthRange = [calendar rangeOfUnit:NSCalendarUnitMonth inUnit:NSCalendarUnitYear forDate:self];
    components.month = monthRange.length;
    
    NSDate *endMonthOfYear = [calendar dateFromComponents:components];
    NSRange dayRange = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:endMonthOfYear];
    components.day = dayRange.length;
    NSDate *endOfYear = [calendar dateFromComponents:components];
    return endOfYear;
}


- (NSString *)timeAgoForTimeline
{
    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *components = [gregorian components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitSecond | NSCalendarUnitMinute) fromDate:self toDate:[NSDate date] options:0];
    if (components.year == 0 && components.month == 0 && components.day == 0)
    {
        if (components.hour > 0)
        {
            return [NSString stringWithFormat:@"%ld小时前",
                    (long)components.hour];
        }
        else if (components.minute > 0)
        {
            return [NSString stringWithFormat:@"%ld分钟前",
                    (long)components.minute];
        }
        else
        {
            return @"刚刚";
        }
    }
    else
    {
        NSDate *nextDate  = [[[NSDate date] nextDay] dateAtStartOfDay];
        NSDateComponents *nextComponents = [gregorian components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitSecond | NSCalendarUnitMinute) fromDate:self toDate:nextDate options:0];
        if (nextComponents.year > 0)
        {
            return [NSString stringWithFormat:@"%ld年前",
                    (long)nextComponents.year];
        }
        else if (nextComponents.month > 0)
        {
            return [NSString stringWithFormat:@"%ld月前",
                    (long)nextComponents.month];
        }
        else if (nextComponents.day > 0)
        {
            if (nextComponents.day == 1)
            {
                return @"昨天";
            }
            else if (nextComponents.day < 7)
            {
                return [NSString stringWithFormat:@"%ld天前",
                        (long)nextComponents.day];
            }
            else if (nextComponents.day < 14)
            {
                return @"1周前";
            }
            else if (nextComponents.day < 21)
            {
                return @"2周前";
            }
            else if (nextComponents.day < 28)
            {
                return @"3周前";
            }
            else if (nextComponents.day >=28)
            {
                return @"4周前";
            }
        }
    }
    return @"刚刚";
}
@end
